// Package go_kit_demo
// Author liuzhiyong
// Date 2023/11/25
// Description
package main

import (
	"flag"
	"gitee.com/liu_zy_developer/go-kit-demo/config"
	"gitee.com/liu_zy_developer/go-kit-demo/logger"
	"gitee.com/liu_zy_developer/go-kit-demo/proto"
	"gitee.com/liu_zy_developer/go-kit-demo/rpc_client"
	"gitee.com/liu_zy_developer/go-kit-demo/service"
	"gitee.com/liu_zy_developer/go-kit-demo/transport"
	"go.uber.org/zap"
	"google.golang.org/grpc"
	"net/http"

	"golang.org/x/sync/errgroup"
	"net"
)

var (
	httpAddr = flag.String("http-addr", ":8080", "HTTP listen address") // 获取命令行参数, 默认:8080
	grpcAddr = flag.String("grpc-addr", ":8972", "gRPC listen address") // 获取命令行参数, 默认:8972
	trimAddr = flag.String("trim-addr", ":8975", "trim server address") //
)

func main() {

	// 初始化,读取配置文件
	var cfn string
	flag.StringVar(&cfn, "conf", "./conf/config.yaml", "指定配置文件路径")
	flag.Parse()
	err := config.Init(cfn)
	if err != nil {
		panic(err) // 程序启动时加载配置文件失败直接退出
	}
	// 初始化zap日志
	err = logger.Init(config.Conf.LogConfig, config.Conf.Mode)
	if err != nil {
		panic(err) // 程序启动时初始化日志模块失败直接退出
	}

	bs := service.NewAddService()

	// 初始化Rpc客户端
	trimEndPoint, err := rpc_client.GetTrimServiceFromConsul("localhost:8500", "trim_service", nil, nil) // log 需要替换成zap的log
	bs = service.NewServiceWithTrim(trimEndPoint, bs)

	var g errgroup.Group

	// HTTP 服务
	g.Go(func() error {
		// 监听㐰
		httpListener, err := net.Listen("tcp", *httpAddr)
		if err != nil {
			zap.L().Error("HTTP server start error.", zap.String("address", *httpAddr), zap.Error(err))
			return err
		}
		defer httpListener.Close()
		// 创建HTTP服务 --> 里面定义了多个HTTP处理器
		httpHandler := transport.NewHTTPServer(bs)
		// 启动HTTP服务器
		return http.Serve(httpListener, httpHandler)
	})
	zap.L().Info("Http Server strat.", zap.String("address", *httpAddr))

	g.Go(func() error {
		// gRPC服务
		grpcListener, err := net.Listen("tcp", *grpcAddr)
		if err != nil {
			zap.L().Error("GRPC server start error.", zap.String("address", *grpcAddr), zap.Error(err))
			return err
		}
		defer grpcListener.Close()
		// 创建grpc服务
		s := grpc.NewServer()
		// 注册Rpc处理器
		proto.RegisterAddServer(s, transport.NewGRPCServer(bs))
		// 启动Rpc服务器
		return s.Serve(grpcListener)
	})
	zap.L().Info("GRPC Server strat.", zap.String("address", *grpcAddr))

	if err := g.Wait(); err != nil {
		zap.L().Error("server exit with err.", zap.Error(err))
	}

}
